namespace MapleRock.P2PEmulator.Core
{
  using System;
  using System.Collections.Generic;
  using System.Diagnostics;
  using System.Linq;
  using System.Text;

  public abstract class Message
  {
    // IP header size can be in the range [20;60] 
    // so assume that it is (20 + 60) / 2 = 40 bytes-long
    public const int IpHeaderSize = 40;

    public const uint BroadcastAddress = uint.MaxValue;

    private uint from = 0;

    private uint to = 0;

    private ulong uid = 0;

    public Message(ulong uid)
    {
      Debug.Assert(uid > 0, "uid > 0");

      this.RoutingState = new MessageRoutingState();
      this.uid = uid;
    }

    public uint From 
    {
      get 
      {
        Debug.Assert(this.from > 0, "this.from > 0");
        return this.from; 
      }

      set
      {
        Debug.Assert(value > 0, "value > 0");
        this.from = value;
      }
    }

    public uint To
    {
      get
      {
        Debug.Assert(this.to > 0, "this.to > 0");
        return this.to;
      }

      set
      {
        Debug.Assert(value > 0, "value > 0");
        this.to = value;
      }
    }

    public ulong Uid
    {
      get
      {
        Debug.Assert(0 != this.uid, "0 != this.uid");
        return this.uid;
      }
    }

    public MessageRoutingState RoutingState { get; set; }

    public abstract int Size { get; }

    // copying all data except for the UID
    public virtual void Assign(Message rhs)
    {
      Debug.Assert(rhs.From >= 0, "rhs.From >= 0");
      this.From = rhs.From;

      Debug.Assert(rhs.To > 0, "rhs.To > 0");
      this.To = rhs.To;
    }

    public abstract Message Duplicate(ulong uid);
  }
}
